function WWallsView(jqContainer) {
	this._jqContainer = jqContainer;
}

WWallsView.prototype.init = function(controller) {
	this._controller = controller;
	this._initBlocks();
};

WWallsView.prototype._initBlocks = function() {
	this._jqBlocks = [];
	var blocks = this._controller.blocks();

	for (var i = 0; i < blocks.length; i++) {
		var block = blocks[i];
		var jqBlock;

		if (block.isVertical()) {
			jqBlock = $('<div class="wblock vwblock">');
			jqBlock.height(50 * block.length());
			this._jqContainer.append(jqBlock);
		} else {
			jqBlock = $('<div class="wblock hwblock">');
			jqBlock.width(50 * block.length());
			this._jqContainer.append(jqBlock);
		}

		this._bindEvents(jqBlock, block);
		this._jqBlocks.push(jqBlock);

		if (block.pivot()) {
			jqBlock.addClass('pivot');
		}
	}
};

WWallsView.prototype.update = function(blocks) {
	for (var i = 0; i < blocks.length; i++) {
		var block = blocks[i];
		var jqBlock = this._jqBlocks[i];
		jqBlock.css('left', block.x() * 50);
		jqBlock.css('top', block.y() * 50);
	}
};

WWallsView.prototype._bindEvents = function(jqBlock, block) {
	var TOP_OR_LEFT = (block.isVertical()) ? 'top' : 'left';
	var DISTANCE_PROP = (block.isVertical()) ? 'deltaY' : 'deltaX';

	var initialPosition = null;
	var BLOCK_W = 50;

	jqBlock.on('mousedown', function(event) {
		initialPosition = jqBlock.position();
	});

	var lastValidIncrement = 0;
	function dragHandler(event) {
		var distance = event.gesture[DISTANCE_PROP];
		var directionSign = sign(distance);
		var direction = directionSign * (1 + Math.floor(Math.abs(distance / BLOCK_W)));

		var canMove = true;
		for (var i = 1; i <= Math.abs(direction); i++) {
			if (!block.canMove(directionSign * i)) {
				canMove = false;
				break;
			}
		}

		if (canMove) {
			lastValidIncrement = direction;
			jqBlock.css(TOP_OR_LEFT, initialPosition[TOP_OR_LEFT] + distance);
		}
	}
	jqBlock.hammer().on('drag', dragHandler);

	jqBlock.hammer().on('dragend', function(event) {
		block.move(lastValidIncrement);

		initialPosition = null;
		direction = null;
		lastValidIncrement = 0;
	});

	function sign(x) {
		return (x > 0) - (x < 0);
	}
};

WWallsView.prototype.onSolved = function() {
	alert('Solved');
	this._unbindEvents();
};

WWallsView.prototype._unbindEvents = function() {
	var jqBlocks = this._jqBlocks;

	for (var i = 0; i < jqBlocks.length; i++) {
		var jaBlock = jqBlocks[i];
		jaBlock.off('mousedown');
		jaBlock.hammer().off('drag');
		jaBlock.hammer().off('dragend');
	}
};